﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class InventoryAdjustService : BaseService, IInventoryAdjustService
    {
        private readonly IInventoryAdjustRepository _inventoryAdjustRepository;
        private readonly IInventoryLogRepository _inventoryLogRepository;
        private readonly IWarehouseRepository _warehouseRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly IMaterialRepository _materialRepository;
        private readonly IAreaRepository _areaRepository;
        private readonly ICellRepository _cellRepository;
        private readonly IUnitOfWork _unitOfWork;
        public InventoryAdjustService(IMapper mapper, IWarehouseRepository _warehouseRepository, IAreaRepository _areaRepository, IInventoryRepository _inventoryRepository, IInventoryAdjustRepository _inventoryAdjustRepository, ICellRepository _cellRepository, IUnitOfWork _unitOfWork, IMaterialRepository materialRepository, IInventoryLogRepository _inventoryLogRepository) : base(mapper)
        {
            this._inventoryAdjustRepository = _inventoryAdjustRepository;
            this._inventoryLogRepository = _inventoryLogRepository;
            this._warehouseRepository = _warehouseRepository;
            this._inventoryRepository = _inventoryRepository;
            this._cellRepository = _cellRepository;
            this._areaRepository = _areaRepository;
            this._unitOfWork = _unitOfWork;
            _materialRepository = materialRepository;
        }

        public bool AddInventoryAdjust(InventoryAdjust m, out string message)
        {
            message = string.Empty;
            var cellobj = _cellRepository.QueryEntityWhere(x=>x.Code==m.LocationCode);
            if (cellobj == null || cellobj.Status != 1)
            {
                message = "仓位信息不存在或已被禁用！";
                return false;
            }
            var inobj = _inventoryRepository.QueryIsEntityWhere(x => x.Id == m.InventoryId && x.Status == 1 && x.IsLock == false);
            if (inobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            m.AreaId = inobj.AreaId;
            m.AreaName = inobj.AreaName;
            m.WhId = inobj.WarehouseId;
            m.WhName = inobj.WarehouseName;
            m.LocationId = inobj.LocationId;
            m.LocationCode = cellobj.Code;
            m.MaterialId = inobj.MaterialId;
            m.MaterialCode = inobj.MaterialCode;
            m.MaterialName = inobj.MaterialName;
            m.PalletBarcode = inobj.PalletBarcode;
            m.Status = 0;
            var mobj = _materialRepository.QueryEntityWhere(x=>x.Code==m.MaterialCode);
            if (mobj == null)
            {
                message = "物料信息有误！";
                return false;
            }
            var maxqty = mobj.MaxSafetyStock;
            var minqty = mobj.MinSafetyStock;
            if(inobj.AvailableQty+m.Qty>maxqty)
            {
                message = "调增后的库存大于该物料最大库存预警！";
                return false;
            }
            else if(inobj.AvailableQty + m.Qty < minqty)
            {
                message = "调增后的库存小于该物料最小库存预警！";
                return false;
            }
            _inventoryAdjustRepository.AddEntity(m);
            return _unitOfWork.SaveChangesEntity();
        }

        public bool AddInventoryAdjustList(List<InventoryAdjust> list, out string message)
        {
            message = string.Empty;
            var celllist = _cellRepository.GetEntityAlls();
            var ilist = _inventoryRepository.GetEntityAlls();
            var materlist = _materialRepository.GetEntityAlls();
            int count = 0;
            string ordersn = "";
            foreach (var item in list)
            {
                if(count==0)
                {                 
                    ordersn = item.BillSN;
                }
                if(count==1)
                {                
                    item.SourceSN = ordersn;
                }
                var cellobj = celllist.FirstOrDefault(x => x.Code == item.LocationCode);
                if (cellobj == null || cellobj.Status != 1)
                {
                    message = "仓位信息不存在或已被禁用！";
                    return false;
                }
                var inobj = ilist.FirstOrDefault(x => x.Id == item.InventoryId && x.Status == 1 && x.IsLock == false);
                if (inobj == null)
                {
                    message = "找不到库存信息！";
                    return false;
                }
                item.Id = YitIdHelper.NextId();
                item.AreaId = inobj.AreaId;
                item.AreaName = inobj.AreaName;
                item.WhId = inobj.WarehouseId;
                item.WhName = inobj.WarehouseName;
                item.LocationId = inobj.LocationId;
                item.LocationCode = cellobj.Code;
                item.MaterialId = inobj.MaterialId;
                item.MaterialCode = inobj.MaterialCode;
                item.MaterialName = inobj.MaterialName;
                item.PalletBarcode = inobj.PalletBarcode;
                item.Status = 0;
                var mobj = _materialRepository.QueryEntityWhere(x => x.Code == item.MaterialCode);
                if (mobj == null)
                {
                    message = "物料信息有误！";
                    return false;
                }
                var maxqty = mobj.MaxSafetyStock;
                var minqty = mobj.MinSafetyStock;
                if (inobj.AvailableQty + item.Qty > maxqty)
                {
                    message = "调增后的库存大于该物料最大库存预警！";
                    return false;
                }
                else if (inobj.AvailableQty + item.Qty < minqty)
                {
                    message = "调增后的库存小于该物料最小库存预警！";
                    return false;
                }
                _inventoryAdjustRepository.AddEntity(item);
                count++;              
            }
            return _unitOfWork.SaveChangesEntity();
        }

        public bool DelInventoryAdjust(long id)
        {
            var iobj = _inventoryAdjustRepository.QueryEntityById(id);
            if(iobj!=null)
            {
                _inventoryAdjustRepository.DelEntity(iobj);
                var idobj = _inventoryAdjustRepository.QueryEntityWhere(x => x.SourceSN == iobj.BillSN);
                if(idobj!=null)
                    _inventoryAdjustRepository.DelEntity(idobj);
                return _unitOfWork.SaveChangesEntity();
            }
            return false;
        }

        public InventoryAdjust? GetInventoryAdjustById(long id)
        {
            return _inventoryAdjustRepository.QueryEntityById(id);
        }

        public List<InventoryAdjust> GetInventoryAdjustList(string? order,int type,int status, int pageIndex, int pageSize, out int totalCount)
        {
            var ilist = _inventoryAdjustRepository.GetEntityAlls();

            //名称
            if (!string.IsNullOrEmpty(order))
            {
                ilist = ilist.Where(x => x.BillSN.Contains(order));
            }
            if(type==20)
            {
                ilist = ilist.Where(x => x.SourceType==type && x.Qty>0);
            }
            else if(type == 10)
            {
                ilist = ilist.Where(x => x.SourceType == type);
            }
            //状态
            if (status != 0)
            {
                ilist = ilist.Where(x => x.Status == status);
            }
            var list = _inventoryAdjustRepository.GetEntityAlls(ilist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return list.ToList();
        }

        public List<InventoryAdjust> GetInventoryAdjustListById(long id)
        {
            List<InventoryAdjust> inventoryAdjusts = new List<InventoryAdjust>();
            var iobj = _inventoryAdjustRepository.QueryEntityById(id);
            if (iobj != null)
            {
                inventoryAdjusts.Add(iobj);
                var idobj = _inventoryAdjustRepository.QueryEntityWhere(x => x.SourceSN == iobj.BillSN);
                if (idobj != null)
                    inventoryAdjusts.Add(idobj);
            }
            return inventoryAdjusts;
        }

        public bool UpdInventoryAdjust(InventoryAdjust m, out string message)
        {
            message = string.Empty;
            var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == m.LocationCode);
            if (cellobj == null || cellobj.Status != 1)
            {
                message = "仓位信息不存在或已被禁用！";
                return false;
            }
            var inobj = _inventoryRepository.QueryIsEntityWhere(x => x.Id == m.InventoryId && x.MaterialId == m.MaterialId && x.Status == 1 && x.IsLock == false);
            if (inobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            m.AreaName = inobj.AreaName;
            m.WhId = inobj.WarehouseId;
            m.WhName = inobj.WarehouseName;
            m.LocationCode = cellobj.Code;
            m.MaterialCode = inobj.MaterialCode;
            m.MaterialName = inobj.MaterialName;
            m.PalletBarcode = inobj.PalletBarcode;
            m.Status = 0;
            var mobj = _materialRepository.QueryEntityById((long)inobj.MaterialId);
            if (mobj == null)
            {
                message = "物料信息有误！";
                return false;
            }
            var maxqty = mobj.MaxSafetyStock;
            var minqty = mobj.MinSafetyStock;
            if (inobj.AvailableQty + m.Qty > maxqty)
            {
                message = "调增后的库存大于该物料最大库存预警！";
                return false;
            }
            else if (inobj.AvailableQty + m.Qty < minqty)
            {
                message = "调增后的库存小于该物料最小库存预警！";
                return false;
            }
            _inventoryAdjustRepository.UpdEntity(m);
            return _unitOfWork.SaveChangesEntity();
        }

        #region 原调整方式实现
        //public bool UpdInventoryAdjustStatus(AuditDto m, out string message)
        //{
        //    message = string.Empty;
        //    var iaobj = _inventoryAdjustRepository.QueryEntityById(m.Id);
        //    if(iaobj != null)
        //    {
        //        iaobj.Status = m.IsOk ? 20 : 30;
        //        iaobj.Reason = m.Remark;
        //        _inventoryAdjustRepository.UpdEntity(iaobj);
        //        var iobj = _inventoryRepository.QueryEntityById(iaobj.InventoryId);
        //        if(iobj==null)
        //        {
        //            message = "找不到库存信息！";
        //            return false;
        //        }
        //        iobj.AvailableQty += iaobj.Qty;
        //        //库存流水
        //        InventoryLog inventoryLog = new InventoryLog()
        //        {
        //            Id = YitIdHelper.NextId(),
        //            SourceType = 3,
        //            SourceSn = iaobj.BillSN,
        //            WarehouseId = iobj.WarehouseId,
        //            WarehouseName = iobj.WarehouseName,
        //            AreaName = iobj.AreaName,
        //            AreaId = iobj.AreaId,
        //            LocationCode = iobj.LocationCode,
        //            PalletBarcode = iobj.PalletBarcode,
        //            MaterialId = iobj.MaterialId,
        //            MaterialCode = iobj.MaterialCode,
        //            MaterialName = iobj.MaterialName,
        //            BatchNo = iobj.BatchNo,
        //            StartQty = iobj.AvailableQty,
        //            ChangeQty = iaobj.Qty,
        //            EndQty = iobj.AvailableQty+iaobj.Qty,
        //            BaseUnitId = iobj.UnitId,
        //            BaseUnitName = iobj.UnitName,
        //            CreateDate = DateTime.Now,
        //            Remark = "库存调整"
        //        };
        //        _inventoryLogRepository.AddEntity(inventoryLog);
        //        return _unitOfWork.SaveChangesEntity();
        //    }
        //    message = "未找到单据";
        //    return false;
        //}
        #endregion
        public bool UpdInventoryAdjustStatus(AuditDto m, out string message)
        {
            message = string.Empty;
            #region 补货加库存
            var iaobj = _inventoryAdjustRepository.QueryEntityById(m.Id);
            if (iaobj != null)
            {
                iaobj.Status = m.IsOk ? 20 : 30;
                iaobj.Reason = m.Remark;
                _inventoryAdjustRepository.UpdEntity(iaobj);
                if(iaobj.Status==30)
                {                 
                    message = "驳回成功！";
                    return _unitOfWork.SaveChangesEntity();
                }
                var iobj = _inventoryRepository.QueryEntityById(iaobj.InventoryId);
                if (iobj == null)
                {
                    message = "找不到库存信息！";
                    return false;
                }
                decimal? qty = iobj.AvailableQty;
                if (iaobj.SourceType == 10)
                {
                    iobj.AvailableQty += iaobj.Qty;
                    //库存流水
                    InventoryLog inventoryLog = new InventoryLog();
                    inventoryLog.Id = YitIdHelper.NextId();
                    inventoryLog.SourceType = 4;
                    inventoryLog.SourceSn = iaobj.BillSN;
                    inventoryLog.WarehouseId = iobj.WarehouseId;
                    inventoryLog.WarehouseName = iobj.WarehouseName;
                    inventoryLog.AreaName = iobj.AreaName;
                    inventoryLog.AreaId = iobj.AreaId;
                    inventoryLog.LocationCode = iobj.LocationCode;
                    inventoryLog.PalletBarcode = iobj.PalletBarcode;
                    inventoryLog.MaterialId = iobj.MaterialId;
                    inventoryLog.MaterialCode = iobj.MaterialCode;
                    inventoryLog.MaterialName = iobj.MaterialName;
                    inventoryLog.BatchNo = iobj.BatchNo;
                    inventoryLog.StartQty = qty;
                    inventoryLog.ChangeQty = iaobj.Qty;
                    inventoryLog.EndQty = iobj.AvailableQty;
                    inventoryLog.BaseUnitId = iobj.UnitId;
                    inventoryLog.BaseUnitName = iobj.UnitName;
                    inventoryLog.CreateDate = DateTime.Now;
                    inventoryLog.Remark = "库存调整";
                    _inventoryLogRepository.AddEntity(inventoryLog);
                }
               
                #region 补货减库存
                var idobj = _inventoryAdjustRepository.QueryEntityWhere(x => x.SourceSN == iaobj.BillSN);
                if(idobj!=null)
                {
                    idobj.Status = m.IsOk ? 20 : 30;
                    idobj.Reason = m.Remark;
                    _inventoryAdjustRepository.UpdEntity(idobj);
                    //var iobj2 = _inventoryRepository.QueryEntityById(idobj.InventoryId);
                    //if (iobj2 == null)
                    //{
                    //    message = "找不到库存信息！";
                    //    return false;
                    //}
                    //if (idobj.SourceType == 10)
                    //    iobj2.AvailableQty += idobj.Qty;
                    //库存流水
                    //InventoryLog inventoryLog2 = new InventoryLog();
                    //inventoryLog2.Id = YitIdHelper.NextId();
                    //inventoryLog2.SourceType = 3;
                    //inventoryLog2.SourceSn = idobj.BillSN;
                    //inventoryLog2.WarehouseId = iobj2.WarehouseId;
                    //inventoryLog2.WarehouseName = iobj2.WarehouseName;
                    //inventoryLog2.AreaName = iobj2.AreaName;
                    //inventoryLog2.AreaId = iobj2.AreaId;
                    //inventoryLog2.LocationCode = iobj2.LocationCode;
                    //inventoryLog2.PalletBarcode = iobj2.PalletBarcode;
                    //inventoryLog2.MaterialId = iobj2.MaterialId;
                    //inventoryLog2.MaterialCode = iobj2.MaterialCode;
                    //inventoryLog2.MaterialName = iobj2.MaterialName;
                    //inventoryLog2.BatchNo = iobj2.BatchNo;
                    //inventoryLog2.StartQty = iobj2.AvailableQty;
                    //inventoryLog2.ChangeQty = idobj.Qty;
                    //inventoryLog2.EndQty = iobj2.AvailableQty + idobj.Qty;
                    //inventoryLog2.BaseUnitId = iobj2.UnitId;
                    //inventoryLog2.BaseUnitName = iobj2.UnitName;
                    //inventoryLog2.CreateDate = DateTime.Now;
                    //inventoryLog2.Remark = "补货调整";
                    //_inventoryLogRepository.AddEntity(inventoryLog2);
                }
                #endregion
                return _unitOfWork.SaveChangesEntity();
            }
            #endregion         
            message = "未找到单据";
            return false;
        }
    }
}
